﻿using System.Numerics;
using Helper;

namespace CSharpBasic;

public class BitOperation
{
    public static void Main()
    {
        new BitOperation().Test();
    }

    private void Test()
    {
        long GetNumByVector2_2(Vector2 pos, Vector3 localEulerAngles)
        {
            // // 99, 999 
            // // 1 1 1 1  1  0  0  1    1  0  0  1
            // // long.maxValue: 9  2233     7203     6854    775    807
            // // long.maxValue:    anglesX  anglesY  anglesZ pos.X  pos.Y
            // int posX = (pos.X < 0 ? 100 : 0 ) + Math.Abs((int)pos.X);
            // int posY = (pos.Y < 0 ? 100 : 0) + Math.Abs((int)pos.Y);
            //
            // int anglesX = (localEulerAngles.X < 0 ? 1000 : 0 ) + Math.Abs((int)localEulerAngles.X);
            // int anglesY = (localEulerAngles.Y < 0 ? 1000 : 0) + Math.Abs((int)localEulerAngles.Y);
            // int anglesZ = (localEulerAngles.Z < 0 ? 1000 : 0) + Math.Abs((int)localEulerAngles.Z);
            //
            // //                   // 100
            // //               // 100 000
            // //          // 1000 000 000
            // //     // 1000 0000 000 000
            // //// 1000 0000 0000 000 000
            // return posY + posX * 1000 + anglesZ * 1000000 + anglesY * 10000000000 + anglesX * 100000000000000;


            // 0000000000 0000000000 0000000000 0000000000 0000000000 00000
            //    lx           ly        lz          x         y        +-
            int posX = Math.Abs((int)pos.X);
            int posY = Math.Abs((int)pos.Y);
            int anglesX = Math.Abs((int)localEulerAngles.X);
            int anglesY = Math.Abs((int)localEulerAngles.Y);
            int anglesZ = Math.Abs((int)localEulerAngles.Z);

            int moveBit = 10;
            long num = anglesX << moveBit;
            num = (num | anglesY) << moveBit;
            num = (num | anglesZ) << moveBit;
            num = (num | posY) << moveBit;
            num = num | posX;
            num = num << 1;
            num = (num | (localEulerAngles.X < 0 ? 1 : 0)) << 1;
            num = (num | (localEulerAngles.Y < 0 ? 1 : 0)) << 1;
            num = (num | (localEulerAngles.Z < 0 ? 1 : 0)) << 1;
            num = (num | (pos.X < 0 ? 1 : 0)) << 1;
            num = num | (pos.Y < 0 ? 1 : 0);

            return num;
        }

        // 根据位运算获取坐标和旋转
        void GetPosAndAngleByNum(long number, out Vector2 pos, out Vector3 angle)
        {
            // 0000000000 0000000000 0000000000 0000000000 0000000000 00000
            //    lx           ly        lz          x         y        +-
            int moveBit = 10;
            int a = 1023;
            long num = number >> 5;
            int posY = (int)num & a;
            num = num >> moveBit;
            int posX = (int)num & a;
            num = num >> moveBit;
            int anglesZ = (int)num & a;
            num = num >> moveBit;
            int anglesY = (int)num & a;
            num = num >> moveBit;
            int anglesX = (int)num & a;

            int sign = (int)number & 1;
            posY = sign == 1 ? -posY : posY;
            sign = (int)number & 2;
            posX = sign == 1 ? -posX : posX;
            sign = (int)number & 4;
            anglesZ = sign == 1 ? -anglesZ : anglesZ;
            sign = (int)number & 8;
            anglesY = sign == 1 ? -anglesY : anglesY;
            sign = (int)number & 16;
            anglesX = sign == 1 ? -anglesX : anglesX;

            pos = new Vector2(posX, posY);
            angle = new Vector3(anglesX, anglesY, anglesZ);
        }

        long num = GetNumByVector2_2(new Vector2(5, -3), new Vector3(11, -90, 0));
        HelperTools.Console_WriteLine_ChangeColor(ConsoleColor.Magenta, num.ToString());
        GetPosAndAngleByNum(num, out Vector2 pos, out Vector3 angle);
    }
}